"""
管理员路由
创建时间：2025-09-12
作者：开发团队
目的：处理管理员功能相关API路由
"""

from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from datetime import date, datetime, timezone
from ..core.database import get_db
from ..services.key_service import (
    create_key, get_keys, archive_key, activate_key, delete_key
)
from ..services.special_visitor_service import (
    get_special_visitors, create_special_visitor, 
    update_special_visitor, delete_special_visitor
)
from ..services.guard_service import (
    get_guards, get_guard_count, create_guard, update_guard, delete_guard, change_guard_password
)
from ..services.audit_service import (
    get_audit_logs, get_audit_log_count
)
from ..schemas.admin import (
    KeyCreate, KeyResponse, SpecialVisitorCreate, SpecialVisitorUpdate,
    SpecialVisitorResponse, GuardCreate, GuardUpdate,
    AuditLogResponse, AuditLogParams, ChangePasswordRequest
)
from ..utils.logger import get_logger

# 导入统计服务
from ..services.statistics_service import (
    get_statistics_summary, get_daily_trend, 
    get_special_visitor_stats
)

# 导入院区服务
from ..services.system_service import get_campuses, get_campus_count

# 创建路由实例
router = APIRouter(prefix="/admin", tags=["管理"])

# 获取日志记录器
logger = get_logger(__name__)


# 密钥管理相关路由
@router.post("/keys", response_model=KeyResponse)
async def create_new_key(
    key_data: KeyCreate,
    db: Session = Depends(get_db)
):
    """
    生成新密钥
    :param key_data: 密钥创建数据
    :param db: 数据库会话
    :return: 创建的密钥信息
    """
    try:
        key = create_key(db, key_data.created_by, key_data.expired_at)
        return key
    except ValueError as e:
        logger.error(f"创建密钥失败: {str(e)}")
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        logger.error(f"创建密钥异常: {str(e)}")
        raise HTTPException(status_code=500, detail="服务器内部错误")


@router.get("/keys", response_model=list[KeyResponse])
async def list_keys(
    skip: int = 0,
    limit: int = 100,
    db: Session = Depends(get_db)
):
    """
    获取密钥列表
    :param skip: 跳过的记录数
    :param limit: 返回的记录数
    :param db: 数据库会话
    :return: 密钥列表
    """
    try:
        keys = get_keys(db, skip, limit)
        return keys
    except Exception as e:
        logger.error(f"获取密钥列表异常: {str(e)}")
        raise HTTPException(status_code=500, detail="服务器内部错误")


@router.put("/keys/{key_id}/archive", response_model=KeyResponse)
async def archive_existing_key(
    key_id: int,
    db: Session = Depends(get_db)
):
    """
    归档密钥
    :param key_id: 密钥ID
    :param db: 数据库会话
    :return: 更新后的密钥信息
    """
    try:
        key = archive_key(db, key_id)
        if not key:
            raise HTTPException(status_code=404, detail="密钥未找到")
        return key
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"归档密钥异常: {str(e)}")
        raise HTTPException(status_code=500, detail="服务器内部错误")


@router.put("/keys/{key_id}/activate", response_model=KeyResponse)
async def activate_existing_key(
    key_id: int,
    db: Session = Depends(get_db)
):
    """
    激活密钥
    :param key_id: 密钥ID
    :param db: 数据库会话
    :return: 更新后的密钥信息
    """
    try:
        key = activate_key(db, key_id)
        if not key:
            raise HTTPException(status_code=404, detail="密钥未找到")
        return key
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"激活密钥异常: {str(e)}")
        raise HTTPException(status_code=500, detail="服务器内部错误")


@router.delete("/keys/{key_id}")
async def delete_existing_key(
    key_id: int,
    db: Session = Depends(get_db)
):
    """
    删除密钥
    :param key_id: 密钥ID
    :param db: 数据库会话
    :return: 删除结果
    """
    try:
        success = delete_key(db, key_id)
        if not success:
            raise HTTPException(status_code=404, detail="密钥未找到")
        return {"message": "密钥删除成功"}
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"删除密钥异常: {str(e)}")
        raise HTTPException(status_code=500, detail="服务器内部错误")


# 特殊访客管理相关路由
@router.get("/special-visitors", response_model=list[SpecialVisitorResponse])
async def list_special_visitors(
    skip: int = 0,
    limit: int = 100,
    db: Session = Depends(get_db)
):
    """
    获取特殊访客列表
    :param skip: 跳过的记录数
    :param limit: 返回的记录数
    :param db: 数据库会话
    :return: 特殊访客列表
    """
    try:
        visitors = get_special_visitors(db, skip, limit)
        return visitors
    except Exception as e:
        logger.error(f"获取特殊访客列表异常: {str(e)}")
        raise HTTPException(status_code=500, detail="服务器内部错误")


@router.post("/special-visitors", response_model=SpecialVisitorResponse)
async def create_new_special_visitor(
    visitor_data: SpecialVisitorCreate,
    db: Session = Depends(get_db)
):
    """
    添加特殊访客
    :param visitor_data: 特殊访客创建数据
    :param db: 数据库会话
    :return: 创建的特殊访客信息
    """
    try:
        visitor = create_special_visitor(db, visitor_data)
        return visitor
    except ValueError as e:
        logger.error(f"创建特殊访客失败: {str(e)}")
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        logger.error(f"创建特殊访客异常: {str(e)}")
        raise HTTPException(status_code=500, detail="服务器内部错误")


@router.put("/special-visitors/{visitor_id}", response_model=SpecialVisitorResponse)
async def update_existing_special_visitor(
    visitor_id: int,
    visitor_data: SpecialVisitorUpdate,
    db: Session = Depends(get_db)
):
    """
    更新特殊访客
    :param visitor_id: 特殊访客ID
    :param visitor_data: 特殊访客更新数据
    :param db: 数据库会话
    :return: 更新后的特殊访客信息
    """
    try:
        visitor = update_special_visitor(db, visitor_id, visitor_data)
        if not visitor:
            raise HTTPException(status_code=404, detail="特殊访客未找到")
        return visitor
    except HTTPException:
        raise
    except ValueError as e:
        logger.error(f"更新特殊访客失败: {str(e)}")
        raise HTTPException(status_code=400, detail=str(e))
    except Exception as e:
        logger.error(f"更新特殊访客异常: {str(e)}")
        raise HTTPException(status_code=500, detail="服务器内部错误")


@router.delete("/special-visitors/{visitor_id}")
async def delete_existing_special_visitor(
    visitor_id: int,
    db: Session = Depends(get_db)
):
    """
    删除特殊访客
    :param visitor_id: 特殊访客ID
    :param db: 数据库会话
    :return: 删除结果
    """
    try:
        success = delete_special_visitor(db, visitor_id)
        if not success:
            raise HTTPException(status_code=404, detail="特殊访客未找到")
        return {"message": "特殊访客删除成功"}
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"删除特殊访客异常: {str(e)}")
        raise HTTPException(status_code=500, detail="服务器内部错误")


# 门卫管理相关路由
@router.get("/guards")
async def list_guards(
    page: int = 1,
    size: int = 100,
    db: Session = Depends(get_db)
):
    """
    获取门卫列表
    :param page: 页码
    :param size: 每页大小
    :param db: 数据库会话
    :return: 门卫列表
    """
    try:
        # 计算偏移量
        skip = (page - 1) * size
        
        guards = get_guards(db, skip, size)
        # 获取门卫总数
        total = get_guard_count(db)
        
        # 返回分页格式响应
        return {
            "code": 200,
            "message": "success",
            "data": {
                "items": guards,
                "total": total,
                "page": page,
                "size": size
            },
            "timestamp": datetime.now(timezone.utc).isoformat()
        }
    except Exception as e:
        logger.error(f"获取门卫列表异常: {str(e)}")
        return {
            "code": 500,
            "message": "服务器内部错误",
            "data": None,
            "error": str(e),
            "timestamp": datetime.now(timezone.utc).isoformat()
        }


@router.put("/guards/{guard_id}/password")
async def change_guard_password_endpoint(
    guard_id: int,
    password_request: ChangePasswordRequest,
    db: Session = Depends(get_db)
):
    """
    修改门卫密码
    :param guard_id: 门卫ID
    :param password_request: 密码修改请求
    :param db: 数据库会话
    :return: 修改结果
    """
    try:
        # 调用服务层修改密码
        success = change_guard_password(db, guard_id, password_request.new_password)
        if success:
            return {
                "code": 200,
                "message": "密码修改成功",
                "data": None,
                "timestamp": datetime.now(timezone.utc).isoformat()
            }
        else:
            return {
                "code": 404,
                "message": "门卫未找到",
                "data": None,
                "error": "门卫未找到",
                "timestamp": datetime.now(timezone.utc).isoformat()
            }
    except Exception as e:
        logger.error(f"修改门卫密码异常: {str(e)}")
        return {
            "code": 500,
            "message": "服务器内部错误",
            "data": None,
            "error": str(e),
            "timestamp": datetime.now(timezone.utc).isoformat()
        }


@router.post("/guards")
async def create_new_guard(
    guard_data: GuardCreate,
    db: Session = Depends(get_db)
):
    """
    添加门卫账号
    :param guard_data: 门卫创建数据
    :param db: 数据库会话
    :return: 创建的门卫信息
    """
    try:
        guard = create_guard(db, guard_data)
        # 返回统一格式响应
        return {
            "code": 200,
            "message": "门卫账号创建成功",
            "data": guard,
            "timestamp": datetime.now(timezone.utc).isoformat()
        }
    except ValueError as e:
        logger.error(f"创建门卫失败: {str(e)}")
        return {
            "code": 400,
            "message": str(e),
            "data": None,
            "error": str(e),
            "timestamp": datetime.now(timezone.utc).isoformat()
        }
    except Exception as e:
        logger.error(f"创建门卫异常: {str(e)}")
        return {
            "code": 500,
            "message": "服务器内部错误",
            "data": None,
            "error": str(e),
            "timestamp": datetime.now(timezone.utc).isoformat()
        }


@router.put("/guards/{guard_id}")
async def update_existing_guard(
    guard_id: int,
    guard_data: GuardUpdate,
    db: Session = Depends(get_db)
):
    """
    更新门卫信息
    :param guard_id: 门卫ID
    :param guard_data: 门卫更新数据
    :param db: 数据库会话
    :return: 更新后的门卫信息
    """
    try:
        guard = update_guard(db, guard_id, guard_data)
        if not guard:
            return {
                "code": 404,
                "message": "门卫未找到",
                "data": None,
                "error": "门卫未找到",
                "timestamp": datetime.now(timezone.utc).isoformat()
            }
        # 返回统一格式响应
        return {
            "code": 200,
            "message": "门卫信息更新成功",
            "data": guard,
            "timestamp": datetime.now(timezone.utc).isoformat()
        }
    except ValueError as e:
        logger.error(f"更新门卫失败: {str(e)}")
        return {
            "code": 400,
            "message": str(e),
            "data": None,
            "error": str(e),
            "timestamp": datetime.now(timezone.utc).isoformat()
        }
    except Exception as e:
        logger.error(f"更新门卫异常: {str(e)}")
        return {
            "code": 500,
            "message": "服务器内部错误",
            "data": None,
            "error": str(e),
            "timestamp": datetime.now(timezone.utc).isoformat()
        }


@router.delete("/guards/{guard_id}")
async def delete_existing_guard(
    guard_id: int,
    db: Session = Depends(get_db)
):
    """
    删除门卫账号
    :param guard_id: 门卫ID
    :param db: 数据库会话
    :return: 删除结果
    """
    try:
        # 调用服务层删除门卫
        success: bool = delete_guard(db, guard_id)
        if success:
            return {
                "code": 200,
                "message": "门卫删除成功",
                "data": None,
                "timestamp": datetime.now(timezone.utc).isoformat()
            }
        else:
            return {
                "code": 404,
                "message": "门卫未找到",
                "data": None,
                "error": "门卫未找到",
                "timestamp": datetime.now(timezone.utc).isoformat()
            }
    except Exception as e:
        logger.error(f"删除门卫异常: {str(e)}")
        return {
            "code": 500,
            "message": "服务器内部错误",
            "data": None,
            "error": str(e),
            "timestamp": datetime.now(timezone.utc).isoformat()
        }


# 统计分析相关路由
@router.get("/statistics")
async def get_statistics(
    start_date: date,
    end_date: date,
    campus_id: int | None = None,
    guard_id: int | None = None,
    db: Session = Depends(get_db)
):
    """
    获取统计数据
    :param start_date: 开始日期
    :param end_date: 结束日期
    :param campus_id: 院区ID（可选）
    :param guard_id: 门卫ID（可选）
    :param db: 数据库会话
    :return: 统计数据
    """
    try:
        # 获取统计摘要
        summary = get_statistics_summary(db, start_date, end_date, campus_id)
        
        # 获取每日趋势
        daily_trend = get_daily_trend(db, start_date, end_date, campus_id)
        
        # 获取特殊访客统计
        special_visitor_stats = get_special_visitor_stats(db, start_date, end_date, campus_id)
        
        # 返回统一格式响应
        return {
            "code": 200,
            "message": "success",
            "data": {
                "summary": summary,
                "daily_trend": daily_trend,
                "special_visitor_stats": special_visitor_stats
            },
            "timestamp": datetime.now(timezone.utc).isoformat()
        }
    except Exception as e:
        logger.error(f"获取统计数据异常: {str(e)}")
        return {
            "code": 500,
            "message": "服务器内部错误",
            "data": None,
            "error": str(e),
            "timestamp": datetime.now(timezone.utc).isoformat()
        }


@router.get("/campuses")
async def list_campuses(
    page: int = 1,
    size: int = 100,
    db: Session = Depends(get_db)
):
    """
    获取院区列表
    :param page: 页码
    :param size: 每页大小
    :param db: 数据库会话
    :return: 院区列表
    """
    try:
        # 计算偏移量
        skip = (page - 1) * size
        
        # 获取院区列表
        campuses = get_campuses(db, skip, size)
        
        # 获取总数
        total = get_campus_count(db)
        
        # 返回分页格式响应
        return {
            "code": 200,
            "message": "success",
            "data": {
                "items": campuses,
                "total": total,
                "page": page,
                "size": size
            },
            "timestamp": datetime.now(timezone.utc).isoformat()
        }
    except Exception as e:
        logger.error(f"获取院区列表异常: {str(e)}")
        return {
            "code": 500,
            "message": "服务器内部错误",
            "data": None,
            "error": str(e),
            "timestamp": datetime.now(timezone.utc).isoformat()
        }


@router.post("/statistics/export")
async def export_statistics_report(
    start_date: date,
    end_date: date,
    campus_id: int | None = None,
    guard_id: int | None = None,
    format: str = "excel",
    db: Session = Depends(get_db)
):
    """
    导出统计报告
    :param start_date: 开始日期
    :param end_date: 结束日期
    :param campus_id: 院区ID（可选）
    :param guard_id: 门卫ID（可选）
    :param format: 导出格式（excel/pdf）
    :param db: 数据库会话
    :return: 导出结果
    """
    try:
        # TODO: 实现统计报告导出功能
        return {
            "code": 200,
            "message": "success",
            "data": {
                "download_url": "",  # TODO: 实现文件生成和下载链接
                "filename": f"statistics_report_{start_date}_to_{end_date}.{format}"
            },
            "timestamp": datetime.now(timezone.utc)
        }
    except Exception as e:
        logger.error(f"导出统计报告异常: {str(e)}")
        return {
            "code": 500,
            "message": "服务器内部错误",
            "data": None,
            "error": str(e),
            "timestamp": datetime.now(timezone.utc)
        }


# 审计日志相关路由
@router.get("/audit-logs", response_model=list[AuditLogResponse])
async def list_audit_logs(
    params: AuditLogParams = Depends(),
    db: Session = Depends(get_db)
):
    """
    获取审计日志列表
    :param params: 查询参数
    :param db: 数据库会话
    :return: 审计日志列表
    """
    try:
        # 解析日期参数
        start_date = None
        end_date = None
        if params.start_date:
            start_date = datetime.strptime(params.start_date, "%Y-%m-%d")
        if params.end_date:
            end_date = datetime.strptime(params.end_date, "%Y-%m-%d")
        
        audit_logs = get_audit_logs(
            db,
            skip=params.skip or 0,
            limit=params.limit or 100,
            user_id=params.user_id,
            action_type=params.action_type,
            start_date=start_date,
            end_date=end_date
        )
        return audit_logs
    except ValueError as e:
        logger.error(f"日期格式错误: {str(e)}")
        raise HTTPException(status_code=400, detail="日期格式错误")
    except Exception as e:
        logger.error(f"获取审计日志列表异常: {str(e)}")
        raise HTTPException(status_code=500, detail="服务器内部错误")


@router.get("/audit-logs/count")
async def get_audit_logs_count(
    params: AuditLogParams = Depends(),
    db: Session = Depends(get_db)
):
    """
    获取审计日志总数
    :param params: 查询参数
    :param db: 数据库会话
    :return: 审计日志总数
    """
    try:
        # 解析日期参数
        start_date = None
        end_date = None
        if params.start_date:
            start_date = datetime.strptime(params.start_date, "%Y-%m-%d")
        if params.end_date:
            end_date = datetime.strptime(params.end_date, "%Y-%m-%d")
        
        count = get_audit_log_count(
            db,
            user_id=params.user_id,
            action_type=params.action_type,
            start_date=start_date,
            end_date=end_date
        )
        
        return {
            "code": 200,
            "message": "success",
            "data": {"count": count},
            "timestamp": datetime.now(timezone.utc)
        }
    except ValueError as e:
        logger.error(f"日期格式错误: {str(e)}")
        raise HTTPException(status_code=400, detail="日期格式错误")
    except Exception as e:
        logger.error(f"获取审计日志总数异常: {str(e)}")
        raise HTTPException(status_code=500, detail="服务器内部错误")